/*
 * Copyright (c) 2011 Norbert Kopcsek
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.modulr.feature {

	import org.modulr.bundle.Bundle;
	import org.modulr.bundle.RequiredFeature;

	[DefaultProperty( "source" )]
	/**
	 * Represents a single feature of the application. A feature consists of one or more bundles defined
	 * in a bundles.xml. Only mandatory features are loaded at startup.
	 *
	 * A feature can be in one of five states:
	 *
	 * - INSTALLED
	 * - QUEUED
	 * - LOADING
	 * - LOADED
	 * - ERROR
	 *
	 * @author Norbert Kopcsek
	 */
	public class Feature {


		//------------------------------------------------------------------------------
		//
		//   Constructor 
		//
		//------------------------------------------------------------------------------

		public function Feature( featureId:String = null, name:String = null, url:String = null, mandatory:Boolean = false ) {
			this.featureId = featureId;
			this.name = name;
			this.url = url;
			this.mandatory = mandatory;
			this.state = FeatureState.INSTALLED;
		}


		//------------------------------------------------------------------------------
		//
		//   Properties (Getter/Setter) 
		//
		//------------------------------------------------------------------------------

		//--------------------------------------
		// featureId 
		//--------------------------------------

		/**
		 * The id of the feature.
		 */
		public function get featureId():String {
			return _featureId;
		}

		public function set featureId( value:String ):void {
			_featureId = value;
		}

		//--------------------------------------
		// name 
		//--------------------------------------

		/**
		 * The name of the feature. The framework does not use this name at all.
		 */
		public function get name():String {
			return _name;
		}

		public function set name( value:String ):void {
			_name = value;
		}

		//--------------------------------------
		// url 
		//--------------------------------------

		/**
		 * The url of the feature.
		 */
		public function get url():String {
			return _url;
		}

		public function set url( value:String ):void {
			_url = value;
		}

		//--------------------------------------
		// isMandatory 
		//--------------------------------------

		/**
		 * Defines whether the feature has to be loaded at startup or not.
		 */
		public function get mandatory():Boolean {
			return _mandatory;
		}

		public function set mandatory( value:Boolean ):void {
			_mandatory = value;
		}

		//--------------------------------------
		// state 
		//--------------------------------------

		/**
		 * A feature can be in one of five states:
		 * - INSTALLED
		 * - QUEUED
		 * - LOADING
		 * - LOADED
		 * - ERROR
		 */
		public function get state():String {
			return _state;
		}

		public function set state( value:String ):void {
			_state = value;
		}

		//--------------------------------------
		// bundlesXml 
		//--------------------------------------

		/**
		 * The bundlesXml loaded for this feature. This xml must be used to install the bundles at the framework.
		 */
		public function get bundlesXml():XML {
			return _bundlesXml;
		}

		public function set bundlesXml( value:XML ):void {
			_bundlesXml = value;
		}

		//--------------------------------------
		// bundles 
		//--------------------------------------

		public function get bundles():Array {
			return _bundles;
		}

		//--------------------------------------
		// requiredFeatures 
		//--------------------------------------

		/**
		 * The requiredFeatures of the feature.
		 */
		public function get requiredFeatures():Array {
			return _requiredFeatures;
		}

		//--------------------------------------
		// requiredByFeatures 
		//--------------------------------------

		/**
		 * The requiredByFeatures of the feature.
		 */
		public function get requiredByFeatures():Array {
			return _requiredByFeature;
		}

		//--------------------------------------
		// source 
		//--------------------------------------

		public function set source( value:Array ):void {

			for each ( var object:Object in value ) {
				if ( object is RequiredFeature ) {
					_requiredFeatures.push( object );
				} else if ( object is Bundle ) {
					_bundles.push( object );
				}
			}
		}


		//------------------------------------------------------------------------------
		//
		//   Protected fields 
		//
		//------------------------------------------------------------------------------

		private var _bundles:Array = [];

		/**
		 * @private
		 */
		private var _featureId:String;

		/**
		 * @private
		 */
		private var _name:String;

		/**
		 * @private
		 */
		private var _url:String;

		/**
		 * @private
		 */
		private var _mandatory:Boolean;

		/**
		 * @private
		 */
		private var _state:String;

		/**
		 * @private
		 */
		private var _bundlesXml:XML;

		/**
		 * @private
		 */
		protected var _requiredFeatures:Array = [];

		/**
		 * @private
		 */
		protected var _requiredByFeature:Array = [];
	}
}

